﻿using System;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Threading;
using Framework.Net.Xmpp.InstantMessaging;
using Microsoft.Practices.Unity;
using XClient.Interfaces;
using XClient.ViewModels;
using Microsoft.Practices.Composite.Regions;
using XClient.Infrastructure;
using System.Windows.Input;
using Framework.Net.Xmpp.Core;

namespace XClient.Views
{
    /// <summary>
    /// Interaction logic for MainView.xaml
    /// </summary>
    public partial class SessionView : UserControl, ISessionView
    {
        #region · Fields ·

        private Dispatcher          dispatcher;
        private SessionViewModel    viewModel;
        private IUnityContainer     container;
        private XmppSession         session;

        #endregion
        
        #region · Properties ·

        public SessionViewModel ViewModel
        {
            get { return this.viewModel; }
            private set
            {
                this.viewModel      = value;
                this.DataContext    = value;
            }
        }

        #endregion

        #region · Constructors ·

        public SessionView(IUnityContainer container)
        {
            InitializeComponent();

            this.container  = container;
            this.dispatcher = Dispatcher.CurrentDispatcher;
            this.ViewModel  = container.Resolve<SessionViewModel>();
            this.session = this.container.Resolve<XmppSession>();

            this.session.StateChanged += new EventHandler<XmppSessionStateChangedEventArgs>(OnSessionStateChanged);
        }

        #endregion

        #region · Private Methods ·

        private void WireEvents()
        {
            this.session.Roster.ContactPresenceChanged += new EventHandler(OnContactPresenceChanged);
        }

        private void UnwireEvents()
        {
            this.session.Roster.ContactPresenceChanged -= new EventHandler(OnContactPresenceChanged);
        }

        #endregion

        #region · Event Handlers ·

        private void OnSessionStateChanged(object sender, XmppSessionStateChangedEventArgs e)
        {
            if (e.NewState == XmppSessionState.LoggingIn)
            {
                this.WireEvents();
            }
            else if (e.NewState == XmppSessionState.LoggingOut)
            {
                this.UnwireEvents();
            }
        }

        private void OnContactPresenceChanged(object sender, EventArgs args)
        {
            this.dispatcher.BeginInvoke(
                DispatcherPriority.ApplicationIdle,
                new ThreadStart(delegate
                {
                    CollectionViewSource viewSource = this.Resources["ContactsViewSource"] as CollectionViewSource;
                    viewSource.View.Refresh();
                }));
        }        

        #endregion

        #region · View Event Handlers ·

        private void UserImage_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.ViewModel.SelectAvatarImage();
        }

        private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            XmppContact contact = (XmppContact)e.Item;

            e.Accepted = (contact.Presence.PresenceStatus != XmppPresenceState.Offline);
        }

        private void ListBoxItem_DoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (this.ContactsListBox.SelectedItem != null)
            {
                XmppContact contact = (XmppContact)this.ContactsListBox.SelectedItem;
                ChatViewManager viewManager = this.container.Resolve<ChatViewManager>();

                // Create the chatView
                viewManager.OpenChatView(contact.ContactId);
            }
        }

        #endregion
    }
}
